﻿using System;
using System.ComponentModel.Design;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using EnvDTE;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Task = System.Threading.Tasks.Task;
using System.Collections.Generic;

namespace VSIXProject_Second
{
    /// <summary>
    /// Command handler
    /// </summary>
    internal sealed class Command
    {

        /// <summary>
        /// Command menu group (command set GUID).
        /// </summary>
        public static readonly Guid CommandSet = new Guid("6b3aed7f-4ac2-446b-9bd4-bf03854ddf53");
        public static readonly Guid CommandView = new Guid("0b942b75-7f0b-4db0-a10e-6e067fa3a673");

        /// <summary>
        /// VS Package that provides this command, not null.
        /// </summary>
        private readonly AsyncPackage package;
        private string SolutionPath = string.Empty;//解决方案所在的目录
        /// <summary>
        /// Initializes a new instance of the <see cref="Command"/> class.
        /// Adds our command handlers for menu (commands must exist in the command table file)
        /// </summary>
        /// <param name="package">Owner package, not null.</param>
        /// <param name="commandService">Command service to add command to, not null.</param>
        private Command(AsyncPackage package, OleMenuCommandService commandService)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            this.package = package ?? throw new ArgumentNullException(nameof(package));
            commandService = commandService ?? throw new ArgumentNullException(nameof(commandService));

            DTE dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;
            if (dte == null)
                return;
            //解决方案名称
            string SolutionFileName = dte.Solution.FileName;
            if (!SolutionFileName.ToUpper().Contains("LeiliTech.ABP.MES".ToUpper()))
                return;
            SolutionPath = SolutionFileName.Substring(0, SolutionFileName.LastIndexOf("\\")).ToUpper();

            var ActionCommandID = new CommandID(CommandSet, 0x0100);
            var ActionCommand = new MenuCommand(ExecuteAction, ActionCommandID);
            commandService.AddCommand(ActionCommand);

            //视图上的转到js
            var JsCommandID = new CommandID(CommandView, 0x0110);
            var JsCommand = new MenuCommand(ExecuteOpenJs, JsCommandID);
            commandService.AddCommand(JsCommand);
            //视图上的点击转到Action
            var ActionCommandID2 = new CommandID(CommandView, 0x0100);
            var ActionCommand2 = new MenuCommand(ExecuteAction, ActionCommandID2);
            commandService.AddCommand(ActionCommand2);

        }

        private void ExecuteAction(object sender, EventArgs e)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            DTE dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;
            if (dte == null)
                return;
            //可能的url集合
            //1.当前文档选中行（有可能一行内存在多个url）
            //2.剪贴板的内容   剪贴板可能一直存在内容，所以优先读取选中行的内容
            List<string> listUrl = new List<string>();
            TextSelection ts = dte.ActiveDocument.Selection as TextSelection;
            ts.SelectLine();
            string content = ts.Text;
            var urls = Regex.Matches(content, "(/\\w+/\\w+/\\w+)");
            foreach (var item in urls)
            {
                listUrl.Add(item.ToString());
            }
            string ClipboardText = System.Windows.Forms.Clipboard.GetText();
            if (!string.IsNullOrEmpty(ClipboardText))
            {
                listUrl.Add(ClipboardText);
            }
            if (listUrl.Count <= 0)
            {
                System.Windows.Forms.MessageBox.Show("请先复制url");
                return;
            }

            string action = "";
            foreach (var item in listUrl)
            {
                var url = item.Replace(@"http://", "");
                string[] arr = url.Split('/');
                if (arr.Length >= 3)
                {
                    string area = "";
                    string controller = "";
                    if (arr.Length == 4)
                    {
                        area = arr[1];
                        controller = arr[2] + "Controller.cs";
                        action = arr[3];
                    }
                    string path = SolutionPath + @"\00_根目录\LeiliTech.MES.Web\Areas\" + area + @"\Controllers";
                    string fileName = controller;
                    string[] files = Directory.GetFiles(path, controller, SearchOption.TopDirectoryOnly);
                    if (files.Length > 0)
                    {
                        dte.ExecuteCommand("File.OpenFile", files[0]);
                        ts = dte.ActiveDocument.Selection as TextSelection;
                        action.Replace("#", "");
                        if (action.IndexOf('?') > -1)
                        {
                            action = action.Substring(0, action.IndexOf('?'));
                        }

                        if (!ts.FindText(action))
                        {
                            ts.FindText(action, (int)vsFindOptions.vsFindOptionsFromStart);
                        }
                        return;
                    }
                    else continue;//匹配的url在项目中找不到文件
                }
                else continue;//不符合条件的url
            }
            //没有找到符合匹配的url
            System.Windows.Forms.MessageBox.Show("未找到匹配的url");
            return;
        }

        private void ExecuteOpenJs(object sender, EventArgs e)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            DTE dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;
            if (dte == null)
                return;
            TextSelection ts = dte.ActiveDocument.Selection as TextSelection;
            ts.SelectLine();
            string viewPath = ts.Text;
            string pathJs = Regex.Match(viewPath, @"~.+\w+.js").Value;
            if (!string.IsNullOrEmpty(pathJs))
            {
                string DocumentFullName = dte.ActiveDocument.FullName;
                string f = "LeiliTech.MES.Web";
                DocumentFullName = DocumentFullName.Substring(0, DocumentFullName.IndexOf(f, StringComparison.OrdinalIgnoreCase) + f.Length);
                pathJs = DocumentFullName + pathJs.Replace("~", "");
                pathJs = pathJs.Replace(@"/", @"\");
                string cmd = "File.OpenFile";
                string args = $"{pathJs}";
                dte.ExecuteCommand(cmd, args);
            }
        }








        /// <summary>
        /// Gets the instance of the command.
        /// </summary>
        public static Command Instance
        {
            get;
            private set;
        }


        /// <summary>
        /// Initializes the singleton instance of the command.
        /// </summary>
        /// <param name="package">Owner package, not null.</param>
        public static async Task InitializeAsync(AsyncPackage package)
        {
            // Switch to the main thread - the call to AddCommand in Command's constructor requires
            // the UI thread.
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken);

            OleMenuCommandService commandService = await package.GetServiceAsync((typeof(IMenuCommandService))) as OleMenuCommandService;
            Instance = new Command(package, commandService);
        }

        /// <summary>
        /// This function is the callback used to execute the command when the menu item is clicked.
        /// See the constructor to see how the menu item is associated with this function using
        /// OleMenuCommandService service and MenuCommand class.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event args.</param>
        private void Execute(object sender, EventArgs e)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            string message = string.Format(CultureInfo.CurrentCulture, "Inside {0}.MenuItemCallback()", this.GetType().FullName);
            string title = "Command";

            // Show a message box to prove we were here
            VsShellUtilities.ShowMessageBox(
                this.package,
                message,
                title,
                OLEMSGICON.OLEMSGICON_INFO,
                OLEMSGBUTTON.OLEMSGBUTTON_OK,
                OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
        }
    }
}
